/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.tabbedproperties.composites;

import java.util.Iterator;
import java.util.List;

import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.jface.text.Assert;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.uml2.uml.Extend;
import org.eclipse.uml2.uml.ExtensionPoint;
import org.eclipse.uml2.uml.LiteralString;
import org.eclipse.uml2.uml.UMLFactory;

import com.cea.papyrus.core.PapyrusPlugin;
import com.cea.papyrus.core.commands.MoveInListCommand;
import com.cea.papyrus.core.editor.CommandStackUtils;
import com.cea.papyrus.core.editpart.IUMLElementEditPart;
import com.cea.papyrus.core.ui.dialogs.ChooseSetExtensionLocationDialog;
import com.cea.papyrus.umlutils.Element;

/**
 * Displays the extension locations of an extend in a composite.
 * 
 * @author Gilles Cannenterre
 * @since 16 nov. 06
 */
public class ExtensionLocationComposite extends DecoratedTableComposite implements ISectionComposite {

	/**
	 * Default Constructor.
	 */
	public ExtensionLocationComposite() {
		super("Extension Location");
	}

	/**
	 * The Constant KEY.
	 */
	private final static String KEY = "extensionlocation_data";
	
	/**
	 * The uml extend.
	 */
	private Extend umlExtend;

	/**
	 * The graphical element extend.
	 */
	private IUMLElementEditPart graphicalElementExtend;

	
	/**
	 * Sets the element.
	 * 
	 * @param element the element
	 */
	@Override
	public void setElement(Element element) {
		super.setElement(element);
		this.umlExtend = (Extend)element.getUml2Element();
	}

	/**
	 * Refresh.
	 */
	@Override
	public void refresh() {
		if( !table.isDisposed()&& (umlExtend!=null)){
			// Remove parameters from table 
			table.removeAll();

			// Read and add parameter
			Iterator<ExtensionPoint> it = umlExtend.getExtensionLocations().iterator();
			while (it.hasNext()) {
				ExtensionPoint extensionpoint = it.next();
				TableItem item = new TableItem(table, SWT.BORDER);
				item.setImage(PapyrusPlugin.getImage(PapyrusPlugin.UML_ICONS_16x16+"ExtensionPoint.gif"));
				item.setData(KEY, extensionpoint);
				item.setText(extensionpoint.getName());
			}
		}
	}
	
	/**
	 * Adds the button pressed.
	 */
	@Override
	public void addButtonPressed() {
		ChooseSetExtensionLocationDialog dialog = new ChooseSetExtensionLocationDialog(composite.getShell(), getElement().getUml2Element());
		dialog.create();
		dialog.setFocus();
		dialog.open();
		if(dialog.hasElementChanged()) {
			refresh();
		}
		
		refreshExtendCondition();
	}

	/**
	 * Down button pressed.
	 */
	@Override
	public void downButtonPressed() {
		CompoundCommand compoundCommand = new CompoundCommand();
		TableItem[] tableItems = table.getSelection();

		for(int i = (tableItems.length-1); i >= 0; i--) {
			// get extension point list
			List extensionPoints = umlExtend.getExtensionLocations();
			// get extension point
			ExtensionPoint extensionPoint = (ExtensionPoint) tableItems[i].getData(KEY);
			int newIndex = table.indexOf(tableItems[i]) + 1;
			if(newIndex < extensionPoints.size()) {
				//new MoveInListCommand(parameters, parameter, newIndex).execute();
				compoundCommand.add(new MoveInListCommand(extensionPoints, extensionPoint, newIndex));
			}
		}
		CommandStack stack = CommandStackUtils.getCommandStack();
		Assert.isNotNull(stack, "Impossible to adapt current editor into a CommandStack");
		stack.execute(compoundCommand);
		
		refreshExtendCondition();
	}

	/**
	 * Edits the item.
	 * 
	 * @param item the item
	 */
	@Override
	public void editItem(TableItem item) {
		if (item == null) {
			return;
		}
		// e linked to the item
		ExtensionPoint extensionPoint = (ExtensionPoint)item.getData(KEY);

		// TODO edit an extension point
	}

	/**
	 * Removes the button pressed.
	 */
	@Override
	public void removeButtonPressed() {
		// get selection and remove it
		TableItem[] tableItems = table.getSelection();
		for(int i = 0; i < tableItems.length ; i++) {
			// get extension point and removed it from the extension location list
			ExtensionPoint extensionPoint = (ExtensionPoint) tableItems[i].getData(KEY);
			umlExtend.getExtensionLocations().remove(extensionPoint);
		}
		
		refreshExtendCondition();
	}

	/**
	 * Up button pressed.
	 */
	@Override
	public void upButtonPressed() {
		CompoundCommand compoundCommand = new CompoundCommand();
		TableItem[] tableItems = table.getSelection();
		// get extension point list
		List extensionPoints = umlExtend.getExtensionLocations();
		// get extension point
		for(int i = 0; i < tableItems.length ; i++) {
			// get extension point
			ExtensionPoint extensionPoint = (ExtensionPoint) tableItems[i].getData(KEY);
			int newIndex = table.indexOf(tableItems[i]) - 1;
			if (newIndex >= 0) {
				compoundCommand.add(new MoveInListCommand(extensionPoints, extensionPoint, newIndex));
			}
		}
		CommandStack stack = CommandStackUtils.getCommandStack();
		Assert.isNotNull(stack, "Impossible to adapt current editor into a CommandStack");
		stack.execute(compoundCommand);
		
		refreshExtendCondition();
	}

	/**
	 * Refresh extend condition.
	 */
	private void refreshExtendCondition() {
		// Initialize condition text
		String conditionText = "";
		
		// If condition extend exists, read the condition text
		if (umlExtend.getCondition() != null){		
			String conditionString = umlExtend.getCondition().getSpecification().stringValue();
			conditionText = conditionString.substring(conditionString.indexOf("{") + 1, conditionString.lastIndexOf("}")).trim();	
		} else {
			// Create condition
			umlExtend.createCondition("extendCondition");
		}	
		
		// Fill condition
		String extendCondition = "  Condition: { " + conditionText + " }  ";
		String extensionPoint = "          ";
		if (!(umlExtend.getExtensionLocations().isEmpty())){
			extensionPoint = ((ExtensionPoint)umlExtend.getExtensionLocations().get(0)).getName();
			extensionPoint = "  extension point: " + extensionPoint + "  ";
		}
		
		LiteralString constraintBody = UMLFactory.eINSTANCE.createLiteralString();
		constraintBody.setValue(extendCondition + "\n" + extensionPoint);
		
		// If no specification, create one
		if (umlExtend.getCondition().getSpecification() == null) {
			umlExtend.getCondition().createSpecification("specification", null, UMLFactory.eINSTANCE.getUMLPackage().getLiteralString());	
		} 
		
		umlExtend.getCondition().setSpecification(constraintBody);	
	}

	/**
	 * Sets the graphical element.
	 * 
	 * @param graphicalElement the graphical element
	 */
	public void setGraphicalElement(IUMLElementEditPart graphicalElement) {
		graphicalElementExtend = graphicalElement;	
	}
}